package com.weiquan.service.impl;

import com.alibaba.fastjson2.JSON;
import com.alibaba.fastjson2.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.weiquan.config.AiConfig;
import com.weiquan.dto.AiDiagnosisRequest;
import com.weiquan.entity.AiDiagnosis;
import com.weiquan.exception.BusinessException;
import com.weiquan.mapper.AiDiagnosisMapper;
import com.weiquan.service.AiService;
import com.weiquan.vo.AiDiagnosisVO;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.*;
import org.springframework.stereotype.Service;
import org.springframework.web.client.RestTemplate;
import org.springframework.web.servlet.mvc.method.annotation.SseEmitter;

import java.io.IOException;
import java.time.LocalDateTime;
import java.util.*;
import java.util.concurrent.CompletableFuture;
import java.util.stream.Collectors;

/**
 * AI服务实现类
 */
@Slf4j
@Service
public class AiServiceImpl extends ServiceImpl<AiDiagnosisMapper, AiDiagnosis> implements AiService {

    @Autowired
    private AiConfig aiConfig;

    @Autowired
    private AiDiagnosisMapper diagnosisMapper;

    private final RestTemplate restTemplate = new RestTemplate();

    // 场景映射
    private static final Map<Integer, String> SCENARIO_MAP = new HashMap<>();
    static {
        SCENARIO_MAP.put(1, "职场纠纷");
        SCENARIO_MAP.put(2, "消费维权");
        SCENARIO_MAP.put(3, "租房矛盾");
        SCENARIO_MAP.put(4, "其他");
    }

    @Override
    public AiDiagnosisVO performDiagnosis(AiDiagnosisRequest request, Long userId) {
        // 创建诊断记录
        AiDiagnosis diagnosis = createDiagnosisRecord(request, userId);
        
        try {
            // 调用AI接口
            String aiResponse = callAiApi(request);
            
            // 解析AI响应
            AiDiagnosisVO result = parseAiResponse(aiResponse, diagnosis);
            
            // 更新诊断记录
            updateDiagnosisRecord(diagnosis, result, 1); // 状态：已完成
            
            return result;
            
        } catch (Exception e) {
            log.error("AI诊断失败", e);
            
            // 更新诊断记录为失败状态
            updateDiagnosisRecord(diagnosis, null, 2); // 状态：失败
            
            // 返回模拟结果
            return createMockDiagnosisResult(request, diagnosis);
        }
    }

    @Override
    public SseEmitter performStreamDiagnosis(AiDiagnosisRequest request, Long userId) {
        SseEmitter emitter = new SseEmitter(60000L); // 60秒超时
        
        // 创建诊断记录
        AiDiagnosis diagnosis = createDiagnosisRecord(request, userId);
        
        // 异步处理
        CompletableFuture.runAsync(() -> {
            try {
                // 模拟流式响应
                sendStreamResponse(emitter, request, diagnosis);
                
            } catch (Exception e) {
                log.error("流式AI诊断失败", e);
                try {
                    emitter.send(SseEmitter.event()
                            .name("error")
                            .data("诊断过程中出现错误，请重试"));
                    emitter.complete();
                } catch (IOException ioException) {
                    log.error("发送错误消息失败", ioException);
                }
            }
        });
        
        return emitter;
    }

    @Override
    public List<AiDiagnosisVO> getDiagnosisHistory(Long userId) {
        QueryWrapper<AiDiagnosis> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("user_id", userId)
                   .orderByDesc("create_time");
        
        List<AiDiagnosis> diagnosisList = diagnosisMapper.selectList(queryWrapper);
        
        return diagnosisList.stream()
                .map(this::convertToVO)
                .collect(Collectors.toList());
    }

    @Override
    public AiDiagnosisVO getDiagnosisDetail(Long diagnosisId, Long userId) {
        AiDiagnosis diagnosis = diagnosisMapper.selectById(diagnosisId);
        
        if (diagnosis == null || diagnosis.getIsDeleted() == 1) {
            throw new BusinessException("诊断记录不存在");
        }
        
        if (!diagnosis.getUserId().equals(userId)) {
            throw new BusinessException("无权访问该诊断记录");
        }
        
        return convertToVO(diagnosis);
    }

    @Override
    public AiDiagnosisVO reDiagnosis(Long diagnosisId, Long userId) {
        AiDiagnosis originalDiagnosis = diagnosisMapper.selectById(diagnosisId);
        
        if (originalDiagnosis == null || originalDiagnosis.getIsDeleted() == 1) {
            throw new BusinessException("原诊断记录不存在");
        }
        
        if (!originalDiagnosis.getUserId().equals(userId)) {
            throw new BusinessException("无权访问该诊断记录");
        }
        
        // 重新构建请求
        AiDiagnosisRequest request = new AiDiagnosisRequest();
        request.setScenario(originalDiagnosis.getScenario());
        request.setProblemDescription(originalDiagnosis.getProblemDescription());
        
        if (originalDiagnosis.getInputData() != null) {
            request.setInputData(JSON.parseObject(originalDiagnosis.getInputData(), Map.class));
        }
        
        return performDiagnosis(request, userId);
    }

    /**
     * 创建诊断记录
     */
    private AiDiagnosis createDiagnosisRecord(AiDiagnosisRequest request, Long userId) {
        AiDiagnosis diagnosis = new AiDiagnosis();
        diagnosis.setUserId(userId);
        diagnosis.setScenario(request.getScenario());
        diagnosis.setProblemDescription(request.getProblemDescription());
        
        if (request.getInputData() != null) {
            diagnosis.setInputData(JSON.toJSONString(request.getInputData()));
        }
        
        diagnosis.setStatus(0); // 进行中
        diagnosis.setCreateTime(LocalDateTime.now());
        diagnosis.setUpdateTime(LocalDateTime.now());
        
        diagnosisMapper.insert(diagnosis);
        return diagnosis;
    }

    /**
     * 调用AI接口
     */
    private String callAiApi(AiDiagnosisRequest request) {
        // 构建请求体
        JSONObject requestBody = new JSONObject();
        requestBody.put("model", aiConfig.getModelName());
        requestBody.put("max_tokens", aiConfig.getMaxTokens());
        requestBody.put("temperature", aiConfig.getTemperature());
        requestBody.put("stream", false);
        
        // 构建消息
        List<Map<String, String>> messages = new ArrayList<>();
        
        // 系统提示
        Map<String, String> systemMessage = new HashMap<>();
        systemMessage.put("role", "system");
        systemMessage.put("content", buildSystemPrompt(request.getScenario()));
        messages.add(systemMessage);
        
        // 用户消息
        Map<String, String> userMessage = new HashMap<>();
        userMessage.put("role", "user");
        userMessage.put("content", buildUserPrompt(request));
        messages.add(userMessage);
        
        requestBody.put("messages", messages);
        
        // 设置请求头
        HttpHeaders headers = new HttpHeaders();
        headers.setContentType(MediaType.APPLICATION_JSON);
        headers.setBearerAuth(aiConfig.getApiKey());
        
        HttpEntity<String> entity = new HttpEntity<>(requestBody.toJSONString(), headers);
        
        // 发送请求
        ResponseEntity<String> response = restTemplate.exchange(
                aiConfig.getBaseUrl() + "/chat/completions",
                HttpMethod.POST,
                entity,
                String.class
        );
        
        return response.getBody();
    }

    /**
     * 构建系统提示词
     */
    private String buildSystemPrompt(Integer scenario) {
        String scenarioName = SCENARIO_MAP.get(scenario);
        
        return String.format(
                "你是一个专业的法律维权助手，专门帮助用户分析%s相关的法律问题。" +
                "请根据用户提供的信息，进行专业的法律分析，并提供以下内容：" +
                "1. 维权成功率评估（0-100的整数）" +
                "2. 关键影响因素分析" +
                "3. 具体的维权步骤建议" +
                "4. 相关法条的通俗解读" +
                "5. 风险提示" +
                "6. 时间和经济成本预估" +
                "请用JSON格式返回结果，确保内容专业、准确、实用。",
                scenarioName
        );
    }

    /**
     * 构建用户提示词
     */
    private String buildUserPrompt(AiDiagnosisRequest request) {
        StringBuilder prompt = new StringBuilder();
        prompt.append("我遇到的问题：").append(request.getProblemDescription()).append("\n");
        
        if (request.getInputData() != null && !request.getInputData().isEmpty()) {
            prompt.append("具体情况：\n");
            request.getInputData().forEach((key, value) -> {
                prompt.append("- ").append(key).append("：").append(value).append("\n");
            });
        }
        
        prompt.append("请帮我分析这个问题，并给出专业的维权建议。");
        
        return prompt.toString();
    }

    /**
     * 解析AI响应
     */
    private AiDiagnosisVO parseAiResponse(String aiResponse, AiDiagnosis diagnosis) {
        try {
            JSONObject response = JSON.parseObject(aiResponse);
            JSONObject choice = response.getJSONArray("choices").getJSONObject(0);
            String content = choice.getJSONObject("message").getString("content");
            
            // 尝试解析JSON格式的响应
            JSONObject result = JSON.parseObject(content);
            
            return buildDiagnosisVO(result, diagnosis);
            
        } catch (Exception e) {
            log.warn("解析AI响应失败，使用模拟数据", e);
            return createMockDiagnosisResult(null, diagnosis);
        }
    }

    /**
     * 构建诊断结果VO
     */
    private AiDiagnosisVO buildDiagnosisVO(JSONObject aiResult, AiDiagnosis diagnosis) {
        AiDiagnosisVO vo = new AiDiagnosisVO();
        vo.setId(diagnosis.getId());
        vo.setScenario(diagnosis.getScenario());
        vo.setScenarioName(SCENARIO_MAP.get(diagnosis.getScenario()));
        vo.setProblemDescription(diagnosis.getProblemDescription());
        vo.setCreateTime(diagnosis.getCreateTime());
        vo.setStatus(diagnosis.getStatus());
        
        // 从AI结果中提取数据（根据实际返回的中文字段）
        try {
            // 提取维权成功率
            String successRateStr = aiResult.getString("维权成功率评估");
            if (successRateStr != null) {
                // 从文本中提取数字
                String[] parts = successRateStr.split("\\D+");
                for (String part : parts) {
                    if (!part.isEmpty()) {
                        vo.setSuccessRate(Integer.parseInt(part));
                        break;
                    }
                }
            }
            if (vo.getSuccessRate() == null) {
                vo.setSuccessRate(50); // 默认值
            }
            vo.setSuccessLevel(getSuccessLevel(vo.getSuccessRate()));
            
            // 提取时间和经济成本预估
            String costEstimate = aiResult.getString("时间和经济成本预估");
            if (costEstimate != null) {
                vo.setEstimatedTime(extractTimeFromText(costEstimate));
                vo.setEstimatedCost(extractCostFromText(costEstimate));
            }
            
            // 构建关键因素列表
            String keyFactorsText = aiResult.getString("关键影响因素分析");
            if (keyFactorsText != null) {
                List<AiDiagnosisVO.KeyFactor> keyFactors = new ArrayList<>();
                AiDiagnosisVO.KeyFactor factor = new AiDiagnosisVO.KeyFactor();
                factor.setName("关键影响因素");
                factor.setDescription(keyFactorsText);
                factor.setImportance(5);
                factor.setHasIt(true);
                factor.setSuggestion("请根据分析结果准备相关材料");
                keyFactors.add(factor);
                vo.setKeyFactors(keyFactors);
            }
            
            // 构建建议步骤列表
            String stepsText = aiResult.getString("具体的维权步骤建议");
            if (stepsText != null) {
                List<AiDiagnosisVO.SuggestedStep> steps = parseStepsFromText(stepsText);
                vo.setSuggestedSteps(steps);
            }
            
            // 构建法条解读列表
            String legalText = aiResult.getString("相关法条的通俗解读");
            if (legalText != null) {
                List<AiDiagnosisVO.LegalAnalysis> legalAnalysis = new ArrayList<>();
                AiDiagnosisVO.LegalAnalysis legal = new AiDiagnosisVO.LegalAnalysis();
                legal.setLawName("相关法律条文");
                legal.setContent(legalText);
                legal.setExplanation(legalText);
                legal.setApplicableScenario("适用于当前情况");
                legalAnalysis.add(legal);
                vo.setLegalAnalysis(legalAnalysis);
            }
            
            // 风险提示
            String riskText = aiResult.getString("风险提示");
            if (riskText != null) {
                List<String> riskWarnings = parseRiskWarnings(riskText);
                vo.setRiskWarnings(riskWarnings);
            }
            
        } catch (Exception e) {
            log.warn("解析AI结果字段失败，使用默认值", e);
            // 设置默认值
            vo.setSuccessRate(50);
            vo.setSuccessLevel("medium");
            vo.setEstimatedTime("2-4周");
            vo.setEstimatedCost("具体费用需要根据案件复杂程度确定");
        }
        
        return vo;
    }
    
    /**
     * 从文本中提取时间信息
     */
    private String extractTimeFromText(String text) {
        if (text == null) return "2-4周";
        
        // 查找时间相关的关键词
        if (text.contains("天")) {
            return text.substring(text.indexOf("时间"), text.indexOf("天") + 1);
        } else if (text.contains("周")) {
            return text.substring(text.indexOf("时间"), text.indexOf("周") + 1);
        } else if (text.contains("月")) {
            return text.substring(text.indexOf("时间"), text.indexOf("月") + 1);
        }
        
        return "2-4周";
    }
    
    /**
     * 从文本中提取费用信息
     */
    private String extractCostFromText(String text) {
        if (text == null) return "具体费用需要根据案件复杂程度确定";
        
        // 查找经济成本相关的内容
        if (text.contains("经济成本")) {
            int start = text.indexOf("经济成本");
            int end = text.length();
            if (text.indexOf("。", start) != -1) {
                end = text.indexOf("。", start) + 1;
            }
            return text.substring(start, end);
        }
        
        return text;
    }
    
    /**
     * 从文本中解析步骤建议
     */
    private List<AiDiagnosisVO.SuggestedStep> parseStepsFromText(String stepsText) {
        List<AiDiagnosisVO.SuggestedStep> steps = new ArrayList<>();
        
        if (stepsText == null || stepsText.trim().isEmpty()) {
            return steps;
        }
        
        // 按数字序号分割步骤
        String[] stepParts = stepsText.split("\\d+\\.");
        int stepNumber = 1;
        
        for (String part : stepParts) {
            if (part.trim().isEmpty()) continue;
            
            AiDiagnosisVO.SuggestedStep step = new AiDiagnosisVO.SuggestedStep();
            step.setStepNumber(stepNumber);
            
            // 提取步骤名称（取第一个冒号前的内容）
            String trimmedPart = part.trim();
            if (trimmedPart.contains("：")) {
                String[] nameParts = trimmedPart.split("：", 2);
                step.setStepName(nameParts[0].trim());
                step.setDescription(nameParts.length > 1 ? nameParts[1].trim() : trimmedPart);
            } else {
                // 如果没有冒号，取前20个字符作为名称
                if (trimmedPart.length() > 20) {
                    step.setStepName(trimmedPart.substring(0, 20) + "...");
                } else {
                    step.setStepName(trimmedPart);
                }
                step.setDescription(trimmedPart);
            }
            
            step.setEstimatedTime("1-2周");
            step.setSuccessImpact("有助于提升维权成功率");
            step.setRequired(true);
            
            steps.add(step);
            stepNumber++;
        }
        
        return steps;
    }
    
    /**
     * 解析风险提示
     */
    private List<String> parseRiskWarnings(String riskText) {
        List<String> warnings = new ArrayList<>();
        
        if (riskText == null || riskText.trim().isEmpty()) {
            return warnings;
        }
        
        // 按数字序号分割风险提示
        String[] riskParts = riskText.split("\\d+\\.");
        
        for (String part : riskParts) {
            if (part.trim().isEmpty()) {
                continue;
            }
            
            String trimmedPart = part.trim();
            // 如果包含冒号，取冒号后的内容
            if (trimmedPart.contains("：")) {
                String[] parts = trimmedPart.split("：", 2);
                if (parts.length > 1) {
                    warnings.add(parts[1].trim());
                } else {
                    warnings.add(trimmedPart);
                }
            } else {
                warnings.add(trimmedPart);
            }
        }
        
        return warnings;
    }

    /**
     * 创建模拟诊断结果
     */
    private AiDiagnosisVO createMockDiagnosisResult(AiDiagnosisRequest request, AiDiagnosis diagnosis) {
        AiDiagnosisVO vo = new AiDiagnosisVO();
        vo.setId(diagnosis.getId());
        vo.setScenario(diagnosis.getScenario());
        vo.setScenarioName(SCENARIO_MAP.get(diagnosis.getScenario()));
        vo.setProblemDescription(diagnosis.getProblemDescription());
        vo.setCreateTime(diagnosis.getCreateTime());
        vo.setStatus(1); // 已完成
        
        // 模拟数据
        vo.setSuccessRate(75);
        vo.setSuccessLevel("medium");
        vo.setEstimatedTime("2-4周");
        vo.setEstimatedCost("500-2000元");
        
        // 模拟关键因素
        List<AiDiagnosisVO.KeyFactor> keyFactors = new ArrayList<>();
        AiDiagnosisVO.KeyFactor factor1 = new AiDiagnosisVO.KeyFactor();
        factor1.setName("证据完整性");
        factor1.setDescription("是否有完整的证据链条");
        factor1.setImportance(5);
        factor1.setHasIt(true);
        factor1.setSuggestion("继续收集相关证据");
        keyFactors.add(factor1);
        vo.setKeyFactors(keyFactors);
        
        // 模拟建议步骤
        List<AiDiagnosisVO.SuggestedStep> steps = new ArrayList<>();
        AiDiagnosisVO.SuggestedStep step1 = new AiDiagnosisVO.SuggestedStep();
        step1.setStepNumber(1);
        step1.setStepName("协商沟通");
        step1.setDescription("首先尝试与对方进行友好协商");
        step1.setEstimatedTime("1-2周");
        step1.setSuccessImpact("提升30%成功率");
        step1.setRequired(true);
        steps.add(step1);
        vo.setSuggestedSteps(steps);
        
        // 模拟法条解读
        List<AiDiagnosisVO.LegalAnalysis> legalAnalysis = new ArrayList<>();
        AiDiagnosisVO.LegalAnalysis legal1 = new AiDiagnosisVO.LegalAnalysis();
        legal1.setLawName("相关法律条文");
        legal1.setContent("法条原文内容");
        legal1.setExplanation("通俗易懂的解释");
        legal1.setApplicableScenario("适用于当前情况");
        legalAnalysis.add(legal1);
        vo.setLegalAnalysis(legalAnalysis);
        
        // 风险提示
        vo.setRiskWarnings(Arrays.asList("注意保存相关证据", "及时采取行动", "寻求专业法律帮助"));
        
        return vo;
    }

    /**
     * 发送流式响应
     */
    private void sendStreamResponse(SseEmitter emitter, AiDiagnosisRequest request, AiDiagnosis diagnosis) throws IOException {
        try {
            // 模拟流式响应过程
            emitter.send(SseEmitter.event().name("start").data("开始分析您的问题..."));
            Thread.sleep(1000);
            
            emitter.send(SseEmitter.event().name("progress").data("正在评估维权成功率..."));
            Thread.sleep(1500);
            
            emitter.send(SseEmitter.event().name("progress").data("正在分析关键影响因素..."));
            Thread.sleep(1500);
            
            emitter.send(SseEmitter.event().name("progress").data("正在生成维权建议..."));
            Thread.sleep(1500);
            
            // 生成最终结果
            AiDiagnosisVO result = createMockDiagnosisResult(request, diagnosis);
            updateDiagnosisRecord(diagnosis, result, 1);
            
            emitter.send(SseEmitter.event().name("result").data(JSON.toJSONString(result)));
            emitter.send(SseEmitter.event().name("complete").data("分析完成"));
            
            emitter.complete();
        } catch (InterruptedException e) {
            log.error("流式响应被中断", e);
            Thread.currentThread().interrupt();
            emitter.send(SseEmitter.event().name("error").data("分析过程被中断"));
            emitter.complete();
        }
    }

    /**
     * 更新诊断记录
     */
    private void updateDiagnosisRecord(AiDiagnosis diagnosis, AiDiagnosisVO result, Integer status) {
        diagnosis.setStatus(status);
        diagnosis.setUpdateTime(LocalDateTime.now());
        
        if (result != null) {
            diagnosis.setSuccessRate(result.getSuccessRate());
            diagnosis.setDiagnosisResult(JSON.toJSONString(result));
            
            if (result.getKeyFactors() != null) {
                diagnosis.setKeyFactors(JSON.toJSONString(result.getKeyFactors()));
            }
            
            if (result.getSuggestedSteps() != null) {
                diagnosis.setSuggestedSteps(JSON.toJSONString(result.getSuggestedSteps()));
            }
            
            if (result.getLegalAnalysis() != null) {
                diagnosis.setLegalAnalysis(JSON.toJSONString(result.getLegalAnalysis()));
            }
        }
        
        diagnosisMapper.updateById(diagnosis);
    }

    /**
     * 转换为VO
     */
    private AiDiagnosisVO convertToVO(AiDiagnosis diagnosis) {
        AiDiagnosisVO vo = new AiDiagnosisVO();
        BeanUtils.copyProperties(diagnosis, vo);
        
        vo.setScenarioName(SCENARIO_MAP.get(diagnosis.getScenario()));
        vo.setSuccessLevel(getSuccessLevel(diagnosis.getSuccessRate()));
        
        // 解析JSON字段
        if (diagnosis.getDiagnosisResult() != null) {
            try {
                AiDiagnosisVO fullResult = JSON.parseObject(diagnosis.getDiagnosisResult(), AiDiagnosisVO.class);
                vo.setKeyFactors(fullResult.getKeyFactors());
                vo.setSuggestedSteps(fullResult.getSuggestedSteps());
                vo.setLegalAnalysis(fullResult.getLegalAnalysis());
                vo.setRiskWarnings(fullResult.getRiskWarnings());
                vo.setEstimatedTime(fullResult.getEstimatedTime());
                vo.setEstimatedCost(fullResult.getEstimatedCost());
            } catch (Exception e) {
                log.warn("解析诊断结果JSON失败", e);
            }
        }
        
        return vo;
    }

    /**
     * 获取成功率等级
     */
    private String getSuccessLevel(Integer successRate) {
        if (successRate == null) return "unknown";
        if (successRate >= 80) return "high";
        if (successRate >= 50) return "medium";
        return "low";
    }
}